﻿using System;
using System.Windows;
using System.Windows.Controls;
using Vlc.DotNet.Core;
using Vlc.DotNet.Core.Medias;
using Vlc.DotNet.Core.Interops.Signatures.LibVlc.Media;
using System.Windows.Input;
using Vlc.DotNet.Wpf;
namespace Helper.Controls
{
    public partial class VlcPlayer : UserControl, IDisposable
    {
        public static readonly DependencyProperty MediaSourceProperty = DependencyProperty.Register("MediaSource", typeof(Uri), 
            typeof(VlcPlayer), new PropertyMetadata(null, new PropertyChangedCallback((o,e)=>
                {
                    if ((e.NewValue != null) && (e.NewValue != DependencyProperty.UnsetValue))
                    {
                        ((VlcPlayer)o).StartPlaying();
                    }
                })));
        private bool myPositionChanging;
        public VlcPlayer()
        {
            if (!VlcContext.IsInitialized)
            {
                try
                {

                    VlcContext.LibVlcDllsPath = @"C:\Program Files (x86)\VideoLAN\VLC";
                    VlcContext.LibVlcPluginsPath = @"C:\Program Files (x86)\VideoLAN\VLC\plugins";
                    VlcContext.StartupOptions.IgnoreConfig = true;
                    VlcContext.StartupOptions.LogOptions.LogInFile = false;
                    VlcContext.StartupOptions.LogOptions.ShowLoggerConsole = false;
                    VlcContext.StartupOptions.LogOptions.Verbosity = VlcLogVerbosities.None;
                    VlcContext.StartupOptions.AddOption("--no-video-title-show");
                    VlcContext.Initialize();
                }
                catch { }
            }

            InitializeComponent();

            myVlcControl.VideoProperties.Scale = 2.0f;
            myVlcControl.TimeChanged += (o, e) =>
                {
                    if (myVlcControl.Media == null)
                        return;
                    var duration = myVlcControl.Media.Duration;
                    durationText.Text = string.Format(
                        "{0:00}:{1:00}:{2:00} / {3:00}:{4:00}:{5:00}",
                        e.Data.Hours,
                        e.Data.Minutes,
                        e.Data.Seconds,
                        duration.Hours,
                        duration.Minutes,
                        duration.Seconds);
                };

            
        }

        ~VlcPlayer()
        {
            myVlcControl.Stop(); 
            VlcContext.CloseAll();
        }

        public void Dispose()
        {
            myVlcControl.Stop();
            VlcContext.CloseAll();
        }

         States PlayerState
        {
            get { return myVlcControl.State; }
        }
        
        public Uri MediaSource
        {
            get { return (Uri)GetValue(MediaSourceProperty); }
            set { SetValue(MediaSourceProperty, value); }
        }

        private void PlayOrPause()
        {
            switch (PlayerState)
            {
                case States.Playing:
                    {
                        myVlcControl.Pause();
                        return;
                    }
                case States.Paused:
                    {
                        myVlcControl.Play();
                        return;
                    }
                default: break;
            }
            myVlcControl.Play();

        }

        private void StartPlaying()
        {
            myVlcControl.Media = new PathMedia(MediaSource.ToString());
            myVlcControl.Media.ParsedChanged += (o, e) =>
            {
                durationText.Text = string.Format(
               "Duration: {0:00}:{1:00}:{2:00}",
               myVlcControl.Media.Duration.Hours,
               myVlcControl.Media.Duration.Minutes,
               myVlcControl.Media.Duration.Seconds);
            };
            myVlcControl.PlaybackMode = Vlc.DotNet.Core.Interops.Signatures.LibVlc.MediaListPlayer.PlaybackModes.Repeat;
        }

        private void OnClickPlay(object sender, RoutedEventArgs e)
        {
            if (myVlcControl.Media != null)
                PlayOrPause();
            else
                StartPlaying();
        }

        private void OnClickStop(object sender, RoutedEventArgs e)
        {
            myVlcControl.Stop();
            position.Value = 0;
        }
        private void VlcControlOnPositionChanged(VlcControl sender, VlcEventArgs<float> e)
        {
            if (myPositionChanging)
           return;
            

            position.Value = e.Data;
        }
        private void SliderMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            myVlcControl.Position = (float)position.Value;
            myVlcControl.PositionChanged += VlcControlOnPositionChanged;

            myPositionChanging = false;
        }
        private void SliderValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (myPositionChanging)
            {
                myVlcControl.Position = (float)e.NewValue;
            }
            //Update the current position text when it is in pause
            var duration = myVlcControl.Media == null ? TimeSpan.Zero : myVlcControl.Media.Duration;
            var time = TimeSpan.FromMilliseconds(duration.TotalMilliseconds * myVlcControl.Position);
            durationText.Text = string.Format(
                "{0:00}:{1:00}:{2:00} / {3:00}:{4:00}:{5:00}",
                time.Hours,
                time.Minutes,
                time.Seconds,
                duration.Hours,
                duration.Minutes,
                duration.Seconds);
        }
        private void SliderMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            myPositionChanging = true;
            myVlcControl.PositionChanged -= VlcControlOnPositionChanged;
        }

    }
}
